// logger_utils.dart
import 'package:logger/logger.dart';

class LoggerUtils {
  static LoggerUtils? _instance;
  static LoggerUtils get instance => _instance ??= LoggerUtils._internal();

  late Logger _logger;
  late LogPrinter _printer;
  Level _currentLevel = Level.debug;
  bool _enable = true;

  LoggerUtils._internal() {
    _setupLogger();
  }

  void _setupLogger() {
    _printer = CustomPrinter();
    _logger = Logger(
      printer: _printer,
      level: Level.trace,
      filter: CustomFilter(),
    );
  }

  /// 配置日志
  void config({
    required Level level,
    required bool enable,
    bool showTime = true,
    bool showEmoji = true,
    bool showStackTrack = false,
  }) {
    _currentLevel = level;
    _enable = enable;

    _logger = Logger(
      printer: CustomPrinter(
        showTime: showTime,
        showEmoji: showEmoji,
        showStackTrack: showStackTrack,
      ),
      level: level,
      filter: CustomFilter(enable: enable, minLevel: level),
    );
  }

  /// 设置日志级别
  void setLevel(Level level) {
    _currentLevel = level;
    _logger = Logger(
      printer: _printer,
      level: level,
      filter: CustomFilter(enable: _enable, minLevel: level),
    );
  }

  /// 启用/禁用日志
  void setEnable(bool enable) {
    _enable = enable;
    _logger = Logger(
      printer: _printer,
      level: _currentLevel,
      filter: CustomFilter(enable: enable, minLevel: _currentLevel),
    );
  }

  /// Verbose 日志 (最详细)
  void v(dynamic message, [dynamic error, StackTrace? stackTrace]) {
    _logger.t(message, error: error, stackTrace: stackTrace);
  }

  /// Debug 日志
  void d(dynamic message, [dynamic error, StackTrace? stackTrace]) {
    _logger.d(message, error: error, stackTrace: stackTrace);
  }

  /// Info 日志
  void i(dynamic message, [dynamic error, StackTrace? stackTrace]) {
    _logger.i(message,  error: error, stackTrace: stackTrace);
  }

  /// Warning 日志
  void w(dynamic message, [dynamic error, StackTrace? stackTrace]) {
    _logger.w(message, error: error, stackTrace: stackTrace);
  }

  /// Error 日志
  void e(dynamic message, [dynamic error, StackTrace? stackTrace]) {
    _logger.e(message,  error: error, stackTrace: stackTrace);
  }

  /// What a Terrible Failure 日志 (最高级别错误)
  void wtf(dynamic message, [dynamic error, StackTrace? stackTrace]) {
    _logger.f(message,  error: error, stackTrace: stackTrace);
  }

  /// 网络请求日志
  void network(
    String url, {
    String method = 'GET',
    dynamic data,
    dynamic response,
  }) {
    if (_currentLevel <= Level.debug) {
      _logger.d('''🌐 NETWORK REQUEST
├─ URL: $method $url
├─ Request: $data
└─ Response: $response''');
    }
  }

  /// API 响应日志
  void apiResponse(
    String path,
    int statusCode,
    dynamic data, {
    String method = 'GET',
  }) {
    String statusEmoji = statusCode >= 200 && statusCode < 300 ? '✅' : '❌';

    if (statusCode >= 400 || _currentLevel <= Level.debug) {
      _logger.i('''$statusEmoji API RESPONSE
├─ $method $path
├─ Status: $statusCode
└─ Data: $data''');
    }
  }

  /// 性能日志
  void performance(String tag, Duration duration) {
    if (duration.inMilliseconds > 1000) {
      // 超过1秒才记录警告
      _logger.w('''⏱️ PERFORMANCE WARNING
├─ Tag: $tag
├─ Duration: ${duration.inMilliseconds}ms
└─ Warning: Operation took too long!''');
    } else if (_currentLevel <= Level.debug) {
      _logger.d('''⏱️ PERFORMANCE
├─ Tag: $tag
└─ Duration: ${duration.inMilliseconds}ms''');
    }
  }

  /// 对象打印 (用于调试复杂对象)
  void printObject(String tag, dynamic object) {
    if (_currentLevel <= Level.trace) {
      _logger.t('''🔍 OBJECT INSPECT: $tag
${_formatObject(object)}''');
    }
  }

  String _formatObject(dynamic object) {
    try {
      if (object is Map) {
        return _formatMap(object);
      } else if (object is List) {
        return _formatList(object);
      } else {
        return object.toString();
      }
    } catch (e) {
      return object.toString();
    }
  }

  String _formatMap(Map<dynamic, dynamic> map, [int indent = 0]) {
    String indentStr = '  ' * indent;
    StringBuffer buffer = StringBuffer();
    buffer.writeln('{');

    map.forEach((key, value) {
      buffer.write('$indentStr  $key: ');
      if (value is Map) {
        buffer.write(_formatMap(value, indent + 1));
      } else if (value is List) {
        buffer.write(_formatList(value, indent + 1));
      } else {
        buffer.write(value);
      }
      buffer.writeln(',');
    });

    buffer.write('$indentStr}');
    return buffer.toString();
  }

  String _formatList(List<dynamic> list, [int indent = 0]) {
    String indentStr = '  ' * indent;
    StringBuffer buffer = StringBuffer();
    buffer.writeln('[');

    for (var item in list) {
      buffer.write('$indentStr  ');
      if (item is Map) {
        buffer.write(_formatMap(item, indent + 1));
      } else if (item is List) {
        buffer.write(_formatList(item, indent + 1));
      } else {
        buffer.write(item);
      }
      buffer.writeln(',');
    }

    buffer.write('$indentStr]');
    return buffer.toString();
  }
}

/// 自定义日志过滤器
class CustomFilter extends LogFilter {
  final bool enable;
  final Level minLevel;

  CustomFilter({this.enable = true, this.minLevel = Level.debug});

  @override
  bool shouldLog(LogEvent event) {
    return enable && event.level.value >= minLevel.value;
  }
}

/// 自定义日志打印机
class CustomPrinter extends LogPrinter {
  final bool showTime;
  final bool showEmoji;
  final bool showStackTrack;

  static final Map<Level, AnsiColor> defaultLevelColors = {
    Level.trace: AnsiColor.fg(AnsiColor.grey(0.5)),
    Level.debug: const AnsiColor.none(),
    Level.info: const AnsiColor.fg(12),
    Level.warning: const AnsiColor.fg(208),
    Level.error: const AnsiColor.fg(196),
    Level.fatal: const AnsiColor.fg(199),
  };

  CustomPrinter({
    this.showTime = true,
    this.showEmoji = true,
    this.showStackTrack = false,
  });

  @override
  List<String> log(LogEvent event) {

    String? emoji = _getEmoji(event.level);
    String levelName = _getLevelName(event.level);
    String time = showTime ? '${DateTime.now().toString().substring(11)} ' : '';
    String emojiStr = showEmoji && emoji != null ? '$emoji ' : '';

    var color = _getLevelColor(event.level);

    var message = event.message;
    var error = event.error;
    var stackTrace = event.stackTrace;

    List<String> lines = [];

    /// 主消息行
    lines.add(color('$time$emojiStr$levelName: $message'));

    /// 错误信息
    if (error != null) {
      lines.add(color('├─ Error: $error'));
    }

    /// 堆栈跟踪
    if (showStackTrack && stackTrace != null) {
      lines.add(color('└─ StackTrace:'));
      var stackLines = stackTrace.toString().split('\n');
      for (var line in stackLines.take(5)) {
        // 只显示前5行
        lines.add(color('      $line'));
      }
      if (stackLines.length > 5) {
        lines.add(color('      ... and ${stackLines.length - 5} more'));
      }
    }

    return lines;
  }

  String? _getEmoji(Level level) {
    switch (level) {
      case Level.trace:
        return '💜';
      case Level.debug:
        return '💚';
      case Level.info:
        return '💙';
      case Level.warning:
        return '💛';
      case Level.error:
        return '❤️';
      case Level.fatal:
        return '💥';
      default:
        return null;
    }
  }

  String _getLevelName(Level level) {
    switch (level) {
      case Level.trace:
        return 'VERBOSE';
      case Level.debug:
        return 'DEBUG';
      case Level.info:
        return 'INFO';
      case Level.warning:
        return 'WARNING';
      case Level.error:
        return 'ERROR';
      case Level.fatal:
        return 'WTF';
      default:
        return level.name;
    }
  }

  AnsiColor _getLevelColor(Level level) {
    AnsiColor? color = defaultLevelColors[level];
    return color ?? const AnsiColor.none();
  }
}
